package com.heima.user.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.apis.article.IArticleClient;
import com.heima.common.constants.user.UserConstants;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.article.pojo.ApAuthor;
import com.heima.model.common.dto.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dto.UserRelationDto;
import com.heima.model.user.pojo.ApUser;
import com.heima.model.user.pojo.ApUserFan;
import com.heima.model.user.pojo.ApUserFollow;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserFollowRelationService;
import com.heima.utils.threadlocal.ApThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;

/**
 * @author Ronaldo
 * @date 2021/8/13
 */
@Service
@Transactional
@Slf4j
public class ApUserFollowRelationServiceImpl implements ApUserFollowRelationService {

    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    @Autowired
    private ApUserMapper apUserMapper;

    @Autowired
    private IArticleClient articleClient;

    @Override
    public ResponseResult saveFollowRelation(UserRelationDto userRelationDto) {

        //参数判断
        if (Objects.isNull(userRelationDto.getAuthorId()) || Objects.isNull(userRelationDto.getArticleId()) || Objects.isNull(userRelationDto.getOperation())){
            throw new LeadNewsException(AppHttpCodeEnum.PARAM_INVALID);
        }

        //判断当前是否用户登录
        ApUser fanUser = ApThreadLocalUtils.getUser();
        if (Objects.isNull(fanUser)){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //根据作者id查询作者是否存在
        ApAuthor author = articleClient.getApAuthorById(userRelationDto.getAuthorId());
        if (Objects.isNull(author)){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_FOUND_AUTHOR);
        }

        //查询作者对象的用户是否存在
        ApUser authorUser = apUserMapper.selectById(author.getUserId());
        if (Objects.isNull(authorUser)){
            throw new LeadNewsException(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        }

        //判断是否自己关注自己
        if (authorUser.getId().equals(fanUser.getId())){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_SUPPORTED_OPERATION_FOCUS_ON_YOURSELF);
        }

        //判断当前是关注还是取消关注
        if (userRelationDto.getOperation().equals(UserConstants.APP_USER_FOLLOW)){
            //关注 ---  保存关系
            insertRelation(fanUser,authorUser,userRelationDto.getArticleId());
        }else {
            //取消关注 --- 删除关系
            deleteRelation(fanUser,authorUser,userRelationDto.getArticleId());
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除关注关系
     * @param fanUser 粉丝用户
     * @param authorUser 作者用户
     * @param articleId 文章id
     */
    private void deleteRelation(ApUser fanUser, ApUser authorUser, Long articleId) {
        Integer fanUserId = fanUser.getId();
        Integer authorUserId = authorUser.getId();

        //判断该用户是否已经关注了该作者
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getUserId, fanUserId)
                .eq(ApUserFollow::getFollowId, authorUserId)
        );
        if (Objects.isNull(apUserFollow)){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_FOLLOW_ONE);
        }

        //判断该作者是否已经有了该粉丝
        ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getUserId, authorUserId)
                .eq(ApUserFan::getFansId, fanUserId)
        );
        if (Objects.isNull(apUserFan)){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_FOLLOW_TWO);
        }

        apUserFanMapper.deleteById(apUserFollow.getId());

        apUserFanMapper.deleteById(apUserFan.getId());
    }

    /**
     * 保存关注关系
     * @param fanUser 粉丝用户
     * @param authorUser 作者用户
     * @param articleId 文章id
     */
    private void insertRelation(ApUser fanUser, ApUser authorUser, Long articleId) {
        Integer fanUserId = fanUser.getId();
        Integer authorUserId = authorUser.getId();

        //判断该用户是否已经关注了该作者
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getUserId, fanUserId)
                .eq(ApUserFollow::getFollowId, authorUserId)
        );
        if (Objects.nonNull(apUserFollow)){
            throw new LeadNewsException(AppHttpCodeEnum.FOLLOWING_ONE);
        }

        //判断该作者是否已经有了该粉丝
        ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getUserId, authorUserId)
                .eq(ApUserFan::getFansId, fanUserId)
        );
        if (Objects.nonNull(apUserFan)){
            throw new LeadNewsException(AppHttpCodeEnum.FOLLOWING_TWO);
        }

        //保存当前用户  关注作者信息
        ApUserFollow userFollow4SaveRelation = new ApUserFollow();
        //当前用户信息
        userFollow4SaveRelation.setUserId(fanUserId);
        //  要关注的作者信息
        userFollow4SaveRelation.setFollowId(authorUserId);
        userFollow4SaveRelation.setFollowName(authorUser.getName());
        userFollow4SaveRelation.setLevel((short)1);
        userFollow4SaveRelation.setIsNotice(Boolean.TRUE);
        userFollow4SaveRelation.setCreatedTime(new Date());

        apUserFollowMapper.insert(userFollow4SaveRelation);

        //保存作者的粉丝信息
        ApUserFan userFan4SaveRelation = new ApUserFan();
        //作者id
        userFan4SaveRelation.setUserId(authorUserId);
        //粉丝id
        userFan4SaveRelation.setFansId(fanUserId.longValue());
        //粉丝名称
        userFan4SaveRelation.setFansName(apUserMapper.selectById(fanUserId).getName());
        userFan4SaveRelation.setLevel((short)0);
        userFan4SaveRelation.setCreatedTime(new Date());
        userFan4SaveRelation.setIsDisplay(Boolean.TRUE);
        userFan4SaveRelation.setIsShieldLetter(Boolean.FALSE);
        userFan4SaveRelation.setIsShieldComment(Boolean.FALSE);
        apUserFanMapper.insert(userFan4SaveRelation);
    }
}
